package com.bingo.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bingo.common.R;
import com.bingo.dao.SaleMapper;
import com.bingo.entity.*;
import com.bingo.entity.dto.HappenedInPeriod;
import com.bingo.entity.dto.SaleA;
import com.bingo.entity.dto.SummarySale;
import com.bingo.entity.dto.everyDayForm.EveryDaySale;
import com.bingo.entity.dto.intermediary.SiteSale;
import com.bingo.entity.dto.resp.ReportBasic;
import com.bingo.entity.dto.resp.RespSiteSale;
import com.bingo.entity.dto.resp.SaleRecord;
import com.bingo.entity.dto.todayForm.TodaySale;
import com.bingo.service.*;
import com.bingo.until.HostHolder;
import com.bingo.until.IsToday;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

@Service
public class SaleServiceImpl extends ServiceImpl<SaleMapper, Sale> implements SaleService {
    private HisPoolService hisPoolService;
    @Autowired
    public void setPoolService(HisPoolService hisPoolService) {
        this.hisPoolService = hisPoolService;
    }

    private HostHolder hostHolder;
    @Autowired
    public void setHostHolder(HostHolder hostHolder) {
        this.hostHolder = hostHolder;
    }

    private CurPoolService curPoolService;
    @Autowired
    public void setPrePoolService(CurPoolService curPoolService) {
        this.curPoolService = curPoolService;
    }

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    private SiteService siteService;

    @Autowired
    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

    @Override
    public R add(String poolNo, Integer saleType, Integer quantity, Double weight, Date date, String userId) {

        userId = hostHolder.getUser().getUserId();

        //查询该塘状态
        CurPool pool = curPoolService.getCurPoolByNo(poolNo);
        if (pool == null) {
            return R.error("不存在该塘!");
        }
        if (pool.getType() == 0) {
            return R.error("该塘是空塘！");
        }

        //查询是否已经存在销售记录
        QueryWrapper<Sale> wrapper = new QueryWrapper<>();
        wrapper.eq("pool_no", poolNo);
        wrapper.eq("date", date);
        wrapper.eq("sale_type", saleType);
        Sale old = this.getOne(wrapper);

        //如果不存在
        if (old == null) {
            //插入销售记录
            Sale sale = new Sale();
            sale.setDate(date);
            sale.setUserId(userId);
            sale.setReportDate(new Date(System.currentTimeMillis()));
            sale.setPoolNo(poolNo);
            sale.setQuantity(quantity);
            sale.setWeight(weight);
            sale.setSaleType(saleType);
            sale.setType(pool.getType());
            this.save(sale);

            //修改塘状态
            pool.setQuantity(pool.getQuantity() - sale.getQuantity());
            pool.setWeight(pool.getWeight() - sale.getWeight());
            curPoolService.updateById(pool);

            //如果不是当天的
            if (!IsToday.isToday(date)) {
                QueryWrapper<HisPool> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("pool_no", poolNo);
                wrapper1.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list = hisPoolService.list(wrapper1);
                for (HisPool p : list) {
                    p.setQuantity(p.getQuantity() - sale.getQuantity());
                    p.setWeight(p.getWeight() - sale.getWeight());
                    hisPoolService.updateById(p);
                }
            }
            R r = R.success("成功");
            r.setStatusText("上报销售记录成功");
            return r;
        } else {
            //计算差值
            int diffQuantity = quantity - old.getQuantity();
            double diffWeight = weight - old.getWeight();
            //修改销售记录
            old.setQuantity(quantity);
            old.setWeight(weight);
            old.setReportDate(new Date(System.currentTimeMillis()));
            old.setUserId(userId);
            this.updateById(old);

            //修改塘状态
            pool.setQuantity(pool.getQuantity() - diffQuantity);
            pool.setWeight(pool.getWeight() - diffWeight);
            curPoolService.updateById(pool);

            //如果不是当天的
            if (!IsToday.isToday(date)) {
                QueryWrapper<HisPool> wrapper2 = new QueryWrapper<>();
                wrapper2.eq("pool_no", poolNo);
                wrapper2.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list = hisPoolService.list(wrapper2);
                for (HisPool p : list) {
                    p.setQuantity(p.getQuantity() - diffQuantity);
                    p.setWeight(p.getWeight() - diffWeight);
                    hisPoolService.updateById(p);
                }
            }


            R r = R.success("修改销售记录成功!");
            return r;

        }


    }

    @Override
    public HappenedInPeriod summarySale(String poolNo, Date startDate, Date endDate) {
        HappenedInPeriod happenedInPeriod = new HappenedInPeriod();
        //普通鳗鱼销售
        QueryWrapper<Sale> saleWrapper = new QueryWrapper<>();
        saleWrapper.eq("pool_no", poolNo);
        saleWrapper.between("date", startDate, endDate);
        saleWrapper.eq("sale_type", 0);
        List<Sale> list = this.list(saleWrapper);
        SummarySale sale = new SummarySale();
        sale.setAmount(0);
        sale.setWeight(0.0);
        for (Sale s : list) {
            sale.setAmount(sale.getAmount() + s.getQuantity());
            sale.setWeight(sale.getWeight() + s.getWeight());
        }
        if (sale.getWeight() == 0 || sale.getAmount() == 0) {
            sale.setSize(0.0);
        } else {
            sale.setSize(sale.getAmount() / sale.getWeight());
        }
        happenedInPeriod.setSummarySale(sale);

        //A鳗销售
        QueryWrapper<Sale> saleAWrapper = new QueryWrapper<>();
        saleAWrapper.eq("pool_no", poolNo);
        saleAWrapper.between("date", startDate, endDate);
        saleAWrapper.eq("sale_type", 1);
        List<Sale> listA = this.list(saleAWrapper);
        SaleA saleA = new SaleA();
        saleA.setAmount(0);
        saleA.setWeight(0.0);
        for (Sale s : listA) {
            saleA.setAmount(saleA.getAmount() + s.getQuantity());
            saleA.setWeight(saleA.getWeight() + s.getWeight());
        }
        happenedInPeriod.setSaleA(saleA);
        return happenedInPeriod;
    }

    @Override
    public List<EveryDaySale> selectEveryDaySale(List<String> poolNos, Date startDate, Date endDate, Integer saleType) {

        if (poolNos == null || poolNos.size() == 0) {
            poolNos = curPoolService.getPoolNos();
        }

        LinkedList<EveryDaySale> list = new LinkedList<>();
        for (String poolNo : poolNos) {
            //初始化数据
            EveryDaySale everyDaySale = new EveryDaySale();
            CurPool pool = curPoolService.getCurPoolByNo(poolNo);
            everyDaySale.setPoolNo(poolNo);
            everyDaySale.setArea(pool.getArea());
            everyDaySale.setKey(poolNo);
            everyDaySale.setTotalQuantity(0);
            everyDaySale.setTotalWeight(0.0);
            everyDaySale.setTotalAQuantity(0);
            everyDaySale.setTotalAWeight(0.0);

            QueryWrapper<Sale> saleWrapper = new QueryWrapper<>();
            saleWrapper.eq("pool_no", poolNo);
            saleWrapper.eq("sale_type", saleType);
            saleWrapper.between("date", startDate, endDate);
            List<Sale> saleList = this.list(saleWrapper);
            //LinkedList<TodaySale> todaySales = new LinkedList<>();
            HashMap<String, TodaySale> hashMap = new HashMap<>();
            //everyDaySale.setDataList(todaySales);
            for (Sale sale : saleList) {
                TodaySale todaySale = new TodaySale();
                todaySale.setPoolNo(sale.getPoolNo());
                todaySale.setQuantity(sale.getQuantity());
                todaySale.setWeight(sale.getWeight());
                todaySale.setType(sale.getType());
                todaySale.setSaleType(sale.getSaleType());
                todaySale.setDate(sale.getDate());
                //todaySales.add(todaySale);

                if (hashMap.containsKey(sale.getDate().toString())) {
                    TodaySale todaySale1 = hashMap.get(sale.getDate().toString());
                    todaySale1.setQuantity(todaySale1.getQuantity() + sale.getQuantity());
                    todaySale1.setWeight(todaySale1.getWeight() + sale.getWeight());
                } else {
                    hashMap.put(sale.getDate().toString(), todaySale);
                }

                if (sale.getSaleType() == 0) {
                    everyDaySale.setTotalQuantity(everyDaySale.getTotalQuantity() + sale.getQuantity());
                    everyDaySale.setTotalWeight(everyDaySale.getTotalWeight() + sale.getWeight());
                } else {
                    everyDaySale.setTotalAQuantity(everyDaySale.getTotalAQuantity() + sale.getQuantity());
                    everyDaySale.setTotalAWeight(everyDaySale.getTotalAWeight() + sale.getWeight());
                }
            }
            everyDaySale.setDataMap(hashMap);
            list.add(everyDaySale);
        }
        return list;
    }

    @Override
    public List<SaleRecord> selectSaleRecord(List<String> poolNos, Date startDate, Date endDate, Integer saleType,String userId) {
        if (poolNos == null || poolNos.size() == 0) {
            poolNos = curPoolService.getPoolNos();
        }

        QueryWrapper<Sale> wrapper = new QueryWrapper<>();
        wrapper.in("pool_no", poolNos);
        wrapper.between("date", startDate, endDate);
        if (userId != null && !userId.equals("")){
            wrapper.eq("user_id", userId);
        }
        wrapper.eq("sale_type", saleType);
        List<Sale> list = this.list(wrapper);

        LinkedList<SaleRecord> saleRecords = new LinkedList<>();
        HashMap<String, String> allUser = userService.getAllUser();

        for (Sale sale : list) {
            SaleRecord saleRecord = new SaleRecord();
            ReportBasic reportBasic = new ReportBasic();
            reportBasic.setPoolNo(sale.getPoolNo());
            String s = allUser.get(sale.getUserId());
            reportBasic.setReporter(s);
            reportBasic.setDate(sale.getDate());
            reportBasic.setReportDate(sale.getReportDate());
            saleRecord.setSaleType(sale.getSaleType());
            saleRecord.setType(sale.getType());
            saleRecord.setQuantity(sale.getQuantity());
            saleRecord.setWeight(sale.getWeight());
            saleRecord.setReportBasic(reportBasic);
            saleRecords.add(saleRecord);
        }

        return saleRecords;
    }

    @Override
    public List<RespSiteSale> selectSiteSale(List<String> siteNos, Date startDate, Date endDate, Integer saleType) {
        if (saleType == null) {
            saleType = 0;
        }
        //如果不传场号查询全部
        if (siteNos == null || siteNos.size() == 0) {
            siteNos = siteService.getAllSiteNo();
        }
        //存返回数据的list
        LinkedList<RespSiteSale> list = new LinkedList<>();

        //遍历场号
        for (String siteNo : siteNos) {
            //初始化数据
            RespSiteSale respSiteSale = this.initRespSiteSale(siteNo);
            respSiteSale.setKey(siteNo + "-new");
            respSiteSale.setType(1);
            RespSiteSale respSiteSaleOld = this.initRespSiteSale(siteNo);
            respSiteSaleOld.setKey(siteNo + "-old");
            respSiteSaleOld.setType(2);

            respSiteSale.setSaleType(saleType);
            respSiteSaleOld.setSaleType(saleType);

            this.initDataMap(respSiteSale, startDate, endDate);
            this.initDataMap(respSiteSaleOld, startDate, endDate);

            list.add(respSiteSale);
            list.add(respSiteSaleOld);

            //查询所有塘号
            List<String> poolNos = curPoolService.getPoolsBySiteNo(siteNo);
            if (poolNos == null || poolNos.size() == 0) {
                continue;
            }

            //查询销售记录
            QueryWrapper<Sale> saleWrapper = new QueryWrapper<>();
            saleWrapper.in("pool_no", poolNos);
            saleWrapper.between("date", startDate, endDate);
            saleWrapper.eq("sale_type", saleType);
            List<Sale> saleList = this.list(saleWrapper);

            //每日数据
            /*for (Sale sale : saleList) {
                //存在当天新鳗
                if (hashMap.containsKey(sale.getDate().toString() + "-new")) {
                    SiteSale siteSale = hashMap.get(sale.getDate().toString() + "-new");
                    if (sale.getSaleType() == 0) {
                        siteSale.setQuantity(siteSale.getQuantity() + sale.getQuantity());
                        siteSale.setWeight(siteSale.getWeight() + sale.getWeight());
                        respSiteSale.setTotalNewQuantity(respSiteSale.getTotalNewQuantity() + sale.getQuantity());
                        respSiteSale.setTotalNewWeight(respSiteSale.getTotalNewWeight() + sale.getWeight());
                    } else {
                        siteSale.setQuantityA(siteSale.getQuantityA() + sale.getQuantity());
                        siteSale.setWeightA(siteSale.getWeightA() + sale.getWeight());
                        respSiteSale.setTotalNewQuantityA(respSiteSale.getTotalNewQuantityA() + sale.getQuantity());
                        respSiteSale.setTotalNewWeightA(respSiteSale.getTotalNewWeightA() + sale.getWeight());
                    }
                }
                //存在当天老鳗
                else if (hashMap.containsKey(sale.getDate().toString() + "-old")) {
                    SiteSale siteSale = hashMap.get(sale.getDate().toString() + "-old");
                    if (sale.getSaleType() == 0) {
                        siteSale.setQuantity(siteSale.getQuantity() + sale.getQuantity());
                        siteSale.setWeight(siteSale.getWeight() + sale.getWeight());
                        respSiteSale.setTotalOldQuantity(respSiteSale.getTotalOldQuantity() + sale.getQuantity());
                        respSiteSale.setTotalOldWeight(respSiteSale.getTotalOldWeight() + sale.getWeight());
                    } else {
                        siteSale.setQuantityA(siteSale.getQuantityA() + sale.getQuantity());
                        siteSale.setWeightA(siteSale.getWeightA() + sale.getWeight());
                        respSiteSale.setTotalOldQuantityA(respSiteSale.getTotalOldQuantityA() + sale.getQuantity());
                        respSiteSale.setTotalOldWeightA(respSiteSale.getTotalOldWeightA() + sale.getWeight());
                    }
                } else {
                    SiteSale siteSale = new SiteSale();
                    siteSale.setDate(sale.getDate());
                    siteSale.setSiteNo(siteNo);
                    siteSale.setQuantity(0);
                    siteSale.setWeight(0.0);
                    siteSale.setQuantityA(0);
                    siteSale.setWeightA(0.0);
                    if (sale.getType() == 1) {
                        if (sale.getSaleType() == 0) {
                            respSiteSale.setTotalNewQuantity(respSiteSale.getTotalNewQuantity() + sale.getQuantity());
                            respSiteSale.setTotalNewWeight(respSiteSale.getTotalNewWeight() + sale.getWeight());
                            siteSale.setQuantity(sale.getQuantity());
                            siteSale.setWeight(sale.getWeight());
                        } else {
                            respSiteSale.setTotalNewQuantityA(respSiteSale.getTotalNewQuantityA() + sale.getQuantity());
                            respSiteSale.setTotalNewWeightA(respSiteSale.getTotalNewWeightA() + sale.getWeight());
                            siteSale.setQuantityA(sale.getQuantity());
                            siteSale.setWeightA(sale.getWeight());
                        }
                        hashMap.put(sale.getDate().toString() + "-new", siteSale);
                    } else if (sale.getType() == 2) {
                        if (sale.getSaleType() == 0) {
                            respSiteSale.setTotalOldQuantity(respSiteSale.getTotalOldQuantity() + sale.getQuantity());
                            respSiteSale.setTotalOldWeight(respSiteSale.getTotalOldWeight() + sale.getWeight());
                            siteSale.setQuantity(sale.getQuantity());
                            siteSale.setWeight(sale.getWeight());
                        } else {
                            respSiteSale.setTotalOldQuantityA(respSiteSale.getTotalOldQuantityA() + sale.getQuantity());
                            respSiteSale.setTotalOldWeightA(respSiteSale.getTotalOldWeightA() + sale.getWeight());
                            siteSale.setQuantityA(sale.getQuantity());
                            siteSale.setWeightA(sale.getWeight());
                        }
                        hashMap.put(sale.getDate().toString() + "-old", siteSale);
                    }
                }

            }*/

            for (Sale sale : saleList) {
                if (sale.getType() == 1) {
                    HashMap<String, SiteSale> dataMap = respSiteSale.getDataMap();
                    SiteSale siteSale = dataMap.get(sale.getDate().toString());
                    siteSale.setQuantity(siteSale.getQuantity() + sale.getQuantity());
                    siteSale.setWeight(siteSale.getWeight() + sale.getWeight());
                    respSiteSale.setTotalQuantity(respSiteSale.getTotalQuantity() + sale.getQuantity());
                    respSiteSale.setTotalWeight(respSiteSale.getTotalWeight() + sale.getWeight());

                } else if (sale.getType() == 2) {
                    HashMap<String, SiteSale> dataMap = respSiteSaleOld.getDataMap();
                    SiteSale siteSale = dataMap.get(sale.getDate().toString());

                    siteSale.setQuantity(siteSale.getQuantity() + sale.getQuantity());
                    siteSale.setWeight(siteSale.getWeight() + sale.getWeight());
                    respSiteSaleOld.setTotalQuantity(respSiteSaleOld.getTotalQuantity() + sale.getQuantity());
                    respSiteSaleOld.setTotalWeight(respSiteSaleOld.getTotalWeight() + sale.getWeight());
                }


            }


        }
        return list;
    }


    private RespSiteSale initRespSiteSale(String siteNo) {
        RespSiteSale respSiteSale = new RespSiteSale();
        respSiteSale.setSiteNo(siteNo);
        Site site = siteService.getSiteByNo(siteNo);
        respSiteSale.setArea(site.getArea());
        respSiteSale.setKey(siteNo);
        respSiteSale.setTotalQuantity(0);
        respSiteSale.setTotalWeight(0.0);
        return respSiteSale;
    }

    private void initDataMap(RespSiteSale respSiteSale, Date startTime, Date endTime) {
        Date tmpDate = new Date(startTime.getTime());
        HashMap<String, SiteSale> dataMap = new HashMap<>();
        //初始化dataMap
        while (tmpDate.getTime() <= endTime.getTime()) {
            SiteSale siteSale = new SiteSale();
            siteSale.setDate(new Date(tmpDate.getTime()));
            siteSale.setSiteNo(respSiteSale.getSiteNo());
            siteSale.setQuantity(0);
            siteSale.setWeight(0.0);
            dataMap.put(tmpDate.toString(), siteSale);
            tmpDate.setTime(tmpDate.getTime() + 24 * 60 * 60 * 1000);
        }
        respSiteSale.setDataMap(dataMap);
    }
}
